package xyz.msj.hrm.service.impl;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import xyz.msj.hrm.constants.CourseRedis;
import xyz.msj.hrm.feign.client.RedisFeignClient;
import xyz.msj.hrm.domain.CourseType;
import xyz.msj.hrm.mapper.CourseTypeMapper;
import xyz.msj.hrm.service.ICourseTypeService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import xyz.msj.hrm.util.AjaxResult;
import xyz.msj.hrm.vo.CrumbsVo;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * <p>
 * 课程目录 服务实现类
 * </p>
 *
 * @author mushengjie
 * @since 2020-09-11
 */
@Service
@Slf4j //开启日志
public class CourseTypeServiceImpl extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {
    //feign的引入
    @Autowired
    private RedisFeignClient redisFeignClient;

    /**
     * 查询课程树和子类
     *
     * @return
     */
    @Override
    public List<CourseType> treeData() {
        //第一种方式：查询父类
        // return baseMapper.treeData(0L);

        //第二种方式
        //查询所有类型
        List<CourseType> allCourseTypes = redisFormDB(); //baseMapper.selectList(null);
        //把扁平化的的课程类型列表，转换成 树状结构的列表
        return treeDataHandler(allCourseTypes);
    }



    /**
     * 查询课程分类面包屑
     *
     * @param productTypeId
     * @return
     */
    @Override
    public List<CrumbsVo> crumbs(Long productTypeId) {
        //根据课程id进行查询，返回课程对象
        CourseType courseType = baseMapper.selectById(productTypeId);
        //获取到当前课程对象的父类课程对象
        String parentIdPath = courseType.getPath();
        //以逗号进行分割
        String[] parentIdString = parentIdPath.split("\\.");
        //查询出多个id对象的课程对象
        List<CourseType> courseTypes = baseMapper.selectBatchIds(Arrays.asList(parentIdString));
        //创建List<CrumbsVo>集合对象
        List<CrumbsVo> result = new ArrayList<>();
        //循环查询兄弟对象
        courseTypes.forEach(c -> {
            //根据当前对象的父类id查询兄弟对象
            List<CourseType> otherProductTypes = baseMapper.selectByPid(c.getPid());
            //移除自己
            otherProductTypes.remove(c);
            //创建vo对象,设值
            CrumbsVo crumbsVo = new CrumbsVo(c,otherProductTypes);
            //添加的集合
            result.add(crumbsVo);
        } );
        //返回
        return result;
    }




    /**
     * 判断是否在缓存中进行查询
     * @return
     */
    private List<CourseType> redisFormDB() {
        //进行查询先从缓存中进行查询,返回查询的结果
        AjaxResult ajaxResult = redisFeignClient.get(CourseRedis.COURSE_REDIS_KEY);
        //对缓存中查询到的数据进行判断 是否有值 返回的结果是否为null
        //有值
        if (ajaxResult.isSuccess() && ajaxResult.getResultObj() != null) {
            //redis中存放的是json字符串  需要先转成字符串  在转换为list集合
            List<CourseType> courseTypes = JSON.parseArray(ajaxResult.getResultObj().toString(), CourseType.class);
            //返回
            return courseTypes;
        }else {
            //对数据库进行查询
            List<CourseType> allCourseTypes = baseMapper.selectList(null);
            //判断是否有值
            //先存一份到redis
            AjaxResult setToRedisAjaxResult  = redisFeignClient.set(CourseRedis.COURSE_REDIS_KEY, JSON.toJSONString(allCourseTypes));

            if (!setToRedisAjaxResult.isSuccess()) {
                //没有存储进去
                log.error("redis缓存失败啦！请及时查看");
            }

            //响应到前台
            return allCourseTypes;
        }
    }

    /**
     *返回父类类型
     * //把扁平化的的课程类型列表，转换成 树状结构的列表
     * @param allCourseTypes
     * @return
     */
    private List<CourseType> treeDataHandler(List<CourseType> allCourseTypes) {
        //一级分类的list
        List<CourseType> firstCourseTypes = new ArrayList<>( );

        for (CourseType allCourseType : allCourseTypes) {
            //2.循环判断找出一级分类，
            if(allCourseType.getPid() == 0){
                //2.1.allCourseType到这里 ，就是一级，添加到list中
                //System.out.println(allCourseType.getName()+"加入一级分类");
                firstCourseTypes.add(allCourseType);
            }else{
                //3.allCourseType到这里，就是非一级，找自己的父分类

                for (CourseType currentParentCourseType : allCourseTypes) {
                    if(allCourseType.getPid().equals(currentParentCourseType.getId())){
                        //3.1.把自己装到父分类的children中
                        //System.out.println(allCourseType.getName()+"加入："+currentParentCourseType.getName()+"的chrild");
                        currentParentCourseType.getChildren().add(allCourseType);
                        break;
                    }
                }
            }
        }
        return firstCourseTypes;
    }


    //如果进添加 删除  修改  需要重置或清除 redis缓存

    /**
     * 清除缓存
     * @param key
     */
    private boolean clearRedis(String key) {
        //清除缓存
        AjaxResult result = redisFeignClient.del(key);
        //如果返回的是false
        if (!result.isSuccess()) {
            log.error("清除缓存失败！请检查");
            return redisFeignClient.del(key).isSuccess();
        }
        return result.isSuccess();
    }

    @Override
    public boolean insert(CourseType entity) {
        boolean result = super.insert(entity);
        //清除缓存
        if (result){
            clearRedis(CourseRedis.COURSE_REDIS_KEY);
        }
        return result;
    }



    @Override
    public boolean updateById(CourseType entity) {
        boolean result = super.updateById(entity);
        //清除缓存
        if (result){
            clearRedis(CourseRedis.COURSE_REDIS_KEY);
        }
        return result;
    }

    @Override
    public boolean deleteById(Serializable id) {
        boolean result = super.deleteById(id);
        //清除缓存
        if (result){
            clearRedis(CourseRedis.COURSE_REDIS_KEY);
        }
        return result;
    }
}